#include <string.h>
#include <iostream>
#include <string>

using std::cout;
using std::endl;
using std::string;

//实例化就是从抽象到具体的过程
/* T----->int */
/* T----->double */
//可以减少代码的书写
/* template <typename T> */
template <class T>
T add(T x, T y)
{
    cout << "T add(T, T)" << endl;
    return x + y;
}

template <class T>
T add(T x, T y, T z)
{
    cout << "T add(T, T, T)" << endl;
    return x + y + z;
}

//函数模板可以与普通函数之间形成重载的
//函数模板与函数模板之间也是可以形成重载的
//普通函数优先于函数模板执行
int add(int x, int y)
{
    cout <<"int add(int,int)" << endl;
    return x + y;
}

//模板的特化
//分类：模板的全特化与模板的偏特化（部分特化）
template <>//模板的特化
const char *add<const char *>(const char *px, const char *py)
{
    cout <<"const char *add(const char *,const char *)" << endl;
    size_t len1 = strlen(px);
    size_t len2 = strlen(py);
    char *ptmp = new char[len1 + len2 + 1]();
    strcpy(ptmp, px);
    strcat(ptmp, py);

    return ptmp;
}

void test()
{
    int ia = 3, ib = 4, ic = 5;
    double da = 3.3, db = 4.4;
    char ca ='a', cb = 1;
    string s1("hello");
    string s2("world");

    cout << "add(ia, ib) = " << add(ia, ib) << endl;//隐式的实例化
    cout << "add(da, db) = " << add<double>(da, db) << endl;//显示的实例化
    cout << "add(ca, cb) = " << add(ca, cb) << endl;
    cout << "add(s1, s2) = " << add(s1, s2) << endl;

    cout << "add(ia, ib, ic) = " << add(ia, ib, ic) << endl;//隐式的实例化
    cout << "add(ia, db) = " << add(ia, db) << endl;

    cout << endl;
    const char *pstr1 = "hello";
    const char *pstr2 = "world";
    cout << "add(pstr1, pstr2) = " << add(pstr1, pstr2) << endl;
}

int main(int argc, char *argv[])
{
    test();
    return 0;
}

